﻿using System;
using System.Configuration;
using System.IO;
using QNUnit.Core;
using QNUnit.Core.Loggers;
using WatiN.Core;

namespace QNUnit.Console
{
    class Program
    {
        #region Fields

        private static string[] _testFiles;
        private static string _suiteName;
        private static ILogger _logger;

        #endregion

        [STAThread]
        static void Main(string[] args)
        {
            InitFields(args);
            LogStartTestSuite();

            foreach (var testFilePath in _testFiles)
            {
                Browser testBrowser;

                if (TestInFirefox())
                    testBrowser = new FireFox(testFilePath);
                else if (TestInIE())
                    testBrowser = new IE(testFilePath, true);
                else
                    throw new Exception("Indicated browser not supported by QNUnit.");

                LogStartTestFile(testBrowser, testFilePath);
                LogTestResults(testBrowser);
                LogEndTestFile(testBrowser, testFilePath);

                testBrowser.Close();
            }

            LogEndTestSuite();
        }

        private static void InitFields(string[] args)
        {
            _testFiles = Directory.GetFiles(args[0], "*.htm");
            _suiteName = ConfigurationManager.AppSettings["testSuiteName"];

            if (IsTeamcityEnabled())
                _logger = new Teamcity(_suiteName);
            else if (IsConsoleEnabled())
                _logger = new ConsoleOut(_suiteName);
            else
                throw new NotSupportedException("Logger type not supported");
        }

        #region Logging
         
        private static void LogStartTestSuite()
        {
            _logger.StartTestSuite();
        }

        private static void LogEndTestSuite()
        {
            _logger.EndTestSuite();
        }

        private static void LogStartTestFile(Browser browser, string fileName)
        {
            var watin = new Watin(browser);
            var testName = watin.GetTestGroupName();

            _logger.StartTestFile(testName, fileName);
        }

        private static void LogEndTestFile(Browser browser, string fileName)
        {
            var watin = new Watin(browser);
            var testName = watin.GetTestGroupName();

            _logger.EndTestFile(testName, fileName);
        }

        private static void LogTestResults(Browser browser)
        {
            var watin = new Watin(browser);
            var qunitTests = watin.GetTests();

            foreach (var qunitTest in qunitTests)
            {
                var subTestIndex = 0;

                foreach (var subTest in qunitTest.SubTests)
                {
                    _logger.StartSubTest(qunitTest.TestName, subTestIndex);

                    if (subTest.HasPassed)
                        _logger.PassSubTest(qunitTest.TestName, subTestIndex, subTest.Message);
                    else
                    {
                        if (subTest.Expected == null)
                            _logger.FailShortSubTest(qunitTest.TestName, subTestIndex, subTest.Message);
                        else
                            _logger.FailSubTest(qunitTest.TestName, subTestIndex, subTest.Message, subTest.Expected, subTest.Actual);
                    }

                    _logger.EndSubTest(qunitTest.TestName, subTestIndex);
                    subTestIndex++;
                }
            }
        }

        #endregion

        #region Configuration

        private static bool TestInIE()
        {
            return (string.Compare(ConfigurationManager.AppSettings["browser"], "ie") == 0);
        }

        private static bool TestInFirefox()
        {
            return (string.Compare(ConfigurationManager.AppSettings["browser"], "firefox") == 0);
        }

        private static bool IsTeamcityEnabled()
        {
            return (string.Compare(ConfigurationManager.AppSettings["logger"], "teamcity") == 0);
        }

        private static bool IsConsoleEnabled()
        {
            return (string.Compare(ConfigurationManager.AppSettings["logger"], "console") == 0);
        }

        #endregion
    }
}
